import pymysql

from conf.conf import MYSQL_CONF
from tools.handle_data import Data
from tools.handle_loguru import logger


# 封装操作Mysql数据库类
class HandleMysql:
    def __init__(self):
        """
        1、初始化建立连接，创建数据库连接
        charset='utf8', 注意，不是utf-8 哦
        返回数据格式控制: cursorclass=pymysql.cursors.DictCursor  加上这个表示返回字典格式的数据；不加的话，以元组的形式返回；
        """
        try:
            self.conn = pymysql.connect(host=MYSQL_CONF["host"],
                                        port=MYSQL_CONF["port"],
                                        user=MYSQL_CONF["user"],
                                        password=MYSQL_CONF["password"],
                                        db=MYSQL_CONF["database"],
                                        autocommit=True,
                                        cursorclass=pymysql.cursors.DictCursor)
            logger.info(f"========= 数据库连接成功，connect对象为：{self.conn} =========")
        except:
            logger.exception("数据库连接失败")

        # 2、创建游标
        self.cur = self.conn.cursor()
        logger.debug(f"游标对象为：{self.cur}")

    # 获取 查询得到的行数(数量)
    def get_count(self, sql):
        logger.debug(f"被执行的sql语句为：{sql}")

        count = self.cur.execute(sql)

        logger.info(f"========= 执行sql语句，数据库显示结果的行数为：{count} =========")
        return count

    # 获取一条数据，一般都是最前面的那条数据
    def get_db_one_data(self, sql, args=None):
        logger.debug(f"被执行的sql语句为：{sql}")

        self.cur.execute(sql, args)
        exe_sql_results = self.cur.fetchone()

        logger.info(f"========= 执行sql语句，第一行数据类型为：{type(exe_sql_results)}，数据为：{exe_sql_results} =========")
        return exe_sql_results

    # 根据sql语句从数据库中获取一个字段的数据，并通过setattr设置为Data类属性。
    def get_db_one_data_and_setattr_data_attribute(self, sql, args=None):
        """
        根据sql语句从数据库中获取一个字段的数据，并通过setattr设置为Data类属性。
        :param sql: 测试用例中sql语句
        :param args: 默认为None
        :return: 无返回值
        """
        logger.debug(f"被执行的sql语句为：{sql}")

        self.cur.execute(sql, args)
        exe_sql_results = self.cur.fetchone()

        logger.info(f"========= 执行sql语句，第一行数据类型为：{type(exe_sql_results)}，数据为：{exe_sql_results} =========")

        # 把查询到的结果设置为Data类属性
        for key_from_db, value_from_db in exe_sql_results.items():
            setattr(Data, key_from_db, value_from_db)
            logger.info(f"执行sql语句得到的变量名是：{key_from_db}，提取到的值是：{value_from_db},并设置为Data类属性。")
        # print(Data.__dict__)

    # 获取全部数据
    def get_db_all_data(self, sql, args=None):
        logger.debug(f"被执行的sql语句为：{sql}")

        self.cur.execute(sql, args)
        exe_sql_results = self.cur.fetchall()

        logger.info(f"========= 执行sql语句后，全部行数据类型为：{type(exe_sql_results)}，数据为：{exe_sql_results} =========")
        return exe_sql_results

    # 关闭数据库连接
    def close(self):
        self.cur.close()
        self.conn.close()     # handle_mysql作为单例模式，一般放在main.py 文件最后关闭即可。
        logger.info(f"========= 数据库游标已关闭、数据库连接已关闭。 =========")


# 使用单例模式，后续导入数据库就只导入 handler_mysql
handle_mysql = HandleMysql()


if __name__ == '__main__':

    # 1、建立链接
    handler_mysql = HandleMysql()

    # 2、执行 sql 语句
    # 先在 sql客户端 (Navicat Premium 12免安装) 执行以下sql语句，查询结果
    phone = 15814479001
    sql_str_1 = f"select * from t_merchant where tel='{phone}'"
    # 执行sql语句，获取一条数据。
    results = handler_mysql.get_db_one_data(sql_str_1)

    sql_str_2 = f"select community_id from t_community order by community_id desc limit 1"
    # 执行sql语句，获取一条数据。
    handler_mysql.get_db_one_data_and_setattr_data_attribute(sql_str_2)

    # 3、执行sql语句，显示受影响的行数。
    count_result = handler_mysql.get_count(sql_str_1)

    # 4、执行sql语句，显示所有受影响的行数。
    sql_str_3 = "select * from t_merchant where merchant_name='深圳文化科技有限公司'"
    all_result = handler_mysql.get_db_all_data(sql_str_3)
